package models

import (
	"context"
	"cv-rpc/config"
	"fmt"
	"log"
	"sync"
	"time"

	"go.mongodb.org/mongo-driver/bson/primitive"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
)

var (
	MClient *mongo.Client
	once    sync.Once
)

type Picture struct {
	ID       primitive.ObjectID `bson:"_id"`
	FileName string             `bson:"filename"`
	Content  []byte             `bson:"content"`
	StartX   int                `bson:"startX"`
	StartY   int                `bson:"startY"`
	Width    int                `bson:"width"`
	Height   int                `bson:"height"`
}

// ConnectToMongo connects to the MongoDB instance using the provided configuration
func ConnectToMongo(cfgPath string) {
	once.Do(func() {
		cfg, err := config.LoadConfig(cfgPath)
		if err != nil {
			log.Fatalf("Failed to load config: %v", err)
		}

		var uri string
		if cfg.Mongo.Username != "" && cfg.Mongo.Password != "" {
			uri = "mongodb://" + cfg.Mongo.Username + ":" + cfg.Mongo.Password + "@" + cfg.Mongo.Host + ":" + cfg.Mongo.Port + "/?authSource=admin"
		} else {
			uri = "mongodb://" + cfg.Mongo.Host + ":" + cfg.Mongo.Port + "/" + cfg.Mongo.Database
		}
		fmt.Println(uri)

		serverAPI := options.ServerAPI(options.ServerAPIVersion1)
		opts := options.Client().ApplyURI(uri).SetServerAPIOptions(serverAPI)

		client, err := mongo.Connect(context.TODO(), opts)
		if err != nil {
			log.Fatalf("Failed to connect to MongoDB: %v", err)
		}

		ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
		defer cancel()
		err = client.Ping(ctx, nil)
		if err != nil {
			log.Fatalf("Failed to ping MongoDB: %v", err)
		}

		MClient = client
		log.Println("Connected to MongoDB!")
	})
}

func GetMongoClient() *mongo.Client {
	return MClient
}
